package plateau;

import java.util.Iterator;

import affichagePlateau.AffichagePlateauFini;
import structureDeDonnee.Cell;
import structureDeDonnee.Matrice;
import structureDeDonnee.Position;

/**
 * 
 * class abstraite implémentant plateau avec les règles d'un monde fini.
 */
public abstract class PlateauFini extends PlateauGeneral {

	/**
	 * hauteur du plateau
	 */
	protected int height;

	/**
	 * largeur du plateau
	 */
	protected int width;
	
	/**
	 * 
	 * @param matrice
	 *            une matrice contenant la liste des cellules vivantes
	 * @param valeursDeSurvie
	 *            un tableau comprenant une liste des valeurs permetant à une
	 *            cellule vivante de rester vivante à l'étape suivant
	 * @param valeursDeNaissance
	 *            un tableau comprenant une liste des valeurs permetant à une
	 *            cellule morte de devenir vivante à l'étape suivante
	 * @param height
	 *            hauteur du plateau
	 * @param width
	 *            largeur du plateau
	 * @throws CelluleHorsPlateauException
	 *             est levé si une des cellules de la matrice est en dehors du
	 *             plateau
	 */
	public PlateauFini(Matrice matrice, int[] valeursDeSurvie,
			int[] valeursDeNaissance, int height, int width)
			throws CelluleHorsPlateauException {
		super(matrice, valeursDeSurvie, valeursDeNaissance);
		this.height = height;
		this.width = width;
		Iterator<Cell> itr = matrice.iterator();
		while (itr.hasNext()) {
			Cell c = itr.next();
			if (enDehorsPlateau(c))
				throw new CelluleHorsPlateauException();
		}
	}

	/**
	 * constructeur
	 * recopie la hauteur la largeur et la liste des cellules vivantes d'un plateau fini
	 * @param plateau un plateau fini 
	 */
	public PlateauFini(PlateauFini plateau) {
		super(plateau.matrice.clone(), plateau.valeursDeSurvie,
				plateau.valeursDeNaissance);
		this.height = plateau.height;
		this.width = plateau.width;
	}

	public int getHeight() {
		return height;
	}

	public int getWidth() {
		return width;
	}

	@Override
	public abstract boolean estUneTranslation(Matrice matrice, Position p);

	@Override
	public abstract Plateau clone();

	@Override
	public boolean afficher() {
		return AffichagePlateauFini.display(this);
	}

	/**
	 * détermine si la cellule donnée en paramètre est en dehors du plateau
	 * appelant
	 * 
	 * @param c
	 *            la cellule que l'on veut tester
	 * @return true si la cellule a des coordonnées non comprises dans le
	 *         plateau appelant
	 */
	public boolean enDehorsPlateau(Cell c) { 
		int posX = c.getPosition().getX();
		int posY = c.getPosition().getY();
		if ((posX >= width) || (posX < 0)) {
			return true;
		} else if ((posY >= height) || (posY < 0)) {
			return true;
		}
		return false;
	}

}
